import '../render'; // 初始化 canvas 和屏幕尺寸
import { SCREEN_WIDTH, SCREEN_HEIGHT } from '../render';
import DataBus from '../databus';
import Table from './table';
import Ball from './ball';
import CueController from './cue';
import AIController from './ai';

const ctx = canvas.getContext('2d');

export default class Main {
  aniId = 0;
  databus = new DataBus();

  table = new Table();
  balls = [];
  cueBall = null;

  cueController = null;
  aiController = null;

  currentPlayer = 'Human'; // 'Human' | 'AI'
  shotInProgress = false;
  ballPocketedThisTurn = false;
  foulThisTurn = false;

  humanScore = 0;
  aiScore = 0;

  constructor() {
    this.start();
  }

  start() {
    this.databus.reset();
    this.initScene();
    cancelAnimationFrame(this.aniId);
    this.aniId = requestAnimationFrame(this.loop.bind(this));
  }

  initScene() {
    // 定义球半径（白球与目标球）
    const rCue = 12;
    const rObj = 11;

    // 白球放在发球区（示例位置，可根据你的 Table 配置调整）
    this.cueBall = new Ball(SCREEN_WIDTH / 2, SCREEN_HEIGHT - 130, rCue, true, '#ffffff');

    // 目标球：倒三角（顶部最多，底部1颗），共15颗
    const gap = rObj * 2 + 2;
    const startX = SCREEN_WIDTH / 2;
    const startY = 160;   // 顶部起始Y
    const totalRows = 5;  // 5排：5,4,3,2,1

    const colors = ['#ff5555', '#55ff55', '#5555ff', '#ffcc00', '#00ccff', '#cc00ff', '#ffaa00', '#00ffaa', '#aa00ff', '#ff0077', '#77ff00', '#0077ff', '#ff8800', '#00ffdd', '#aa66ff'];
    let idx = 0;

    for (let i = 0; i < totalRows; i++) {
      const count = totalRows - i;             // 当前排的数量：5,4,3,2,1
      const rowY = startY + i * gap;
      const rowWidth = (count - 1) * gap;
      const rowLeft = startX - rowWidth / 2;

      for (let col = 0; col < count; col++) {
        const x = rowLeft + col * gap;
        const y = rowY;
        const color = colors[idx % colors.length];
        this.balls.push(new Ball(x, y, rObj, false, color));
        idx++;
      }
    }

    // 加入白球
    this.balls.push(this.cueBall);

    // 控杆
    this.cueController = new CueController(this.cueBall, (dir, power) => {
      if (!this.canHumanShoot()) return;
      this.cueBall.vx = dir.x * power;
      this.cueBall.vy = dir.y * power;
      this.notifyShotStarted();
    });

    // AI
    this.aiController = new AIController(this.cueBall, this.getObjectBalls(), this);

    // 人类先手
    this.startTurn();
  }

  getObjectBalls() {
    return this.balls.filter((b) => !b.isCueBall);
  }

  startTurn() {
    this.ballPocketedThisTurn = false;
    this.foulThisTurn = false;

    if (this.currentPlayer === 'Human') {
      this.cueController.enableForTurn(true);
    } else {
      this.cueController.enableForTurn(false);
      this.aiController.takeShot();
    }
  }

  canHumanShoot() {
    return this.currentPlayer === 'Human' && !this.shotInProgress && !this.databus.isGameOver;
  }

  notifyShotStarted() {
    this.shotInProgress = true;
  }

  allBallsStopped() {
    return this.balls.every((b) => b.isPocketed || !b.isMoving());
  }

  placeCueBallForOpponent() {
    const pos = this.table.getHeadStringPosition();
    this.cueBall.reset(pos.x, pos.y);
    this.cueController.clearAimLine();
  }

  onBallPocketed(ball) {
    this.ballPocketedThisTurn = true;
    if (this.currentPlayer === 'Human') this.humanScore += ball.points;
    else this.aiScore += ball.points;
  }

  onCueBallPocketed() {
    this.foulThisTurn = true;
  }

  resolveTurn() {
    if (this.foulThisTurn) {
      this.placeCueBallForOpponent();
      this.switchPlayer();
      this.startTurn();
      return;
    }

    if (this.ballPocketedThisTurn) {
      this.checkGameEnd();
      this.startTurn();
      return;
    }

    this.switchPlayer();
    this.checkGameEnd();
    this.startTurn();
  }

  switchPlayer() {
    this.currentPlayer = this.currentPlayer === 'Human' ? 'AI' : 'Human';
  }

  checkGameEnd() {
    const allPocketed = this.getObjectBalls().every((b) => b.isPocketed);
    if (allPocketed) {
      this.databus.gameOver();
      // 简单打印结果
      const winner = this.humanScore >= this.aiScore ? '玩家胜利' : 'AI胜利';
      console.log(`游戏结束！玩家 ${this.humanScore} 分，AI ${this.aiScore} 分。${winner}`);
    }
  }

  // 物理更新：位移、阻尼、边界碰撞、球-球碰撞、进袋检测
  update(dt) {
    this.databus.frame++;
    if (this.databus.isGameOver) return;

    // 新增：驱动回弹动画
    this.cueController.update(dt);

    // 位移与阻尼
    for (const b of this.balls) {
      if (b.isPocketed) continue;
      b.update(dt);
      this.table.resolveWallCollision(b);
    }

    // 球-球碰撞
    for (let i = 0; i < this.balls.length; i++) {
      for (let j = i + 1; j < this.balls.length; j++) {
        const a = this.balls[i];
        const b = this.balls[j];
        if (a.isPocketed || b.isPocketed) continue;
        this.resolveBallCollision(a, b);
      }
    }

    // 进袋判定
    for (const b of this.balls) {
      if (b.isPocketed) continue;
      const pocket = this.table.checkPocket(b);
      if (pocket) {
        b.pocket();
        if (b.isCueBall) this.onCueBallPocketed();
        else this.onBallPocketed(b);
      }
    }

    // 回合结束判定：所有球静止后再做回合结算
    if (this.shotInProgress && this.allBallsStopped()) {
      this.shotInProgress = false;
      this.resolveTurn();
    }
  }

  // 简化的等质量弹性碰撞
  resolveBallCollision(a, b) {
    const dx = b.x - a.x;
    const dy = b.y - a.y;
    let dist = Math.sqrt(dx * dx + dy * dy);
    const minDist = a.r + b.r;

    if (dist === 0) dist = 0.0001;

    if (dist < minDist) {
      const nx = dx / dist;
      const ny = dy / dist;

      // 分离以消除重叠
      const overlap = minDist - dist;
      a.x -= nx * overlap * 0.5;
      a.y -= ny * overlap * 0.5;
      b.x += nx * overlap * 0.5;
      b.y += ny * overlap * 0.5;

      // 速度分解到法线/切线
      const tx = -ny;
      const ty = nx;

      const va_n = a.vx * nx + a.vy * ny;
      const vb_n = b.vx * nx + b.vy * ny;

      const va_t = a.vx * tx + a.vy * ty;
      const vb_t = b.vx * tx + b.vy * ty;

      // 等质量弹性：交换法向分量，切向不变
      const e = 0.98; // 恢复系数略小于1
      const va_n_after = vb_n * e;
      const vb_n_after = va_n * e;

      a.vx = va_n_after * nx + va_t * tx;
      a.vy = va_n_after * ny + va_t * ty;

      b.vx = vb_n_after * nx + vb_t * tx;
      b.vy = vb_n_after * ny + vb_t * ty;
    }
  }

  render() {
    ctx.clearRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

    // 绘制台面与袋口
    this.table.render(ctx);

    // 绘制球
    for (const b of this.balls) {
      if (!b.isPocketed) b.render(ctx);
    }

    // 玩家瞄准线
    if (this.currentPlayer === 'Human') {
      this.cueController.render(ctx);
    }

    // HUD
    ctx.fillStyle = '#ffffff';
    ctx.font = '16px Arial';
    ctx.fillText(`玩家:${this.humanScore}  AI:${this.aiScore}`, 12, 22);
    ctx.fillText(`回合: ${this.currentPlayer}`, 12, 42);

    // 新增：显示实心/花球剩余数量
    const solidsLeft = this.getObjectBalls().filter(b => !b.isPocketed && b.ballType === 'solid').length;
    const stripesLeft = this.getObjectBalls().filter(b => !b.isPocketed && b.ballType === 'stripe').length;
    ctx.fillText(`实心剩余: ${solidsLeft}  花球剩余: ${stripesLeft}`, 12, 62);

    if (this.databus.isGameOver) {
      ctx.fillText('游戏结束，点击屏幕重新开始', 12, 84);
    }
  }

  loop(ts) {
    // 简单 dt 估算
    const dt = 1 / 60;

    this.update(dt);
    this.render();

    this.aniId = requestAnimationFrame(this.loop.bind(this));
  }
}